package org.dtp.listener;

import com.alibaba.cloud.nacos.NacosConfigProperties;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.AbstractListener;
import com.alibaba.nacos.api.exception.NacosException;
import org.dtp.DynamicThreadPoolManager;
import org.dtp.config.DynamicThreadPoolProperties;
import org.dtp.config.ThreadPoolProperties;
import org.dtp.utils.JsonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.yaml.snakeyaml.Yaml;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @ClassName NacosCloudConfigUpdateListener
 * @Description Spring Cloud Alibaba Nacos配置修改监听
 * @Author wangyiqi
 * @Date 2021-08-14-11:11
 **/
public class NacosCloudConfigUpdateListener {

    @Autowired
    private NacosConfigProperties nacosConfigProperties;

    @Autowired
    private DynamicThreadPoolManager dynamicThreadPoolManager;

    @Resource
    private DynamicThreadPoolProperties dynamicThreadPoolProperties;

    @PostConstruct
    public void init() {
        initConfigUpdateListener();
    }

    private void initConfigUpdateListener() {
        ConfigService configService = nacosConfigProperties.configServiceInstance();
        if (Objects.isNull(dynamicThreadPoolProperties.getNacosDataId())) {
            throw new RuntimeException("not found dynamic.threadpools.nacosDataId");
        }
        if (Objects.isNull(dynamicThreadPoolProperties.getNacosGroup())) {
            throw new RuntimeException("not found dynamic.threadpools.nacosGroup");
        }

        try {
            configService.addListener(dynamicThreadPoolProperties.getNacosDataId(), dynamicThreadPoolProperties.getNacosGroup(), new AbstractListener() {
                @Override
                public void receiveConfigInfo(String configInfo) {
                    Map map = new Yaml().loadAs(configInfo, Map.class);
                    Map dynamic = (Map) map.get("dynamic");
                    if (Objects.isNull(dynamic)) {
                        return;
                    }
                    Map threadpools = (Map) dynamic.get("threadpools");
                    if (Objects.isNull(threadpools)) {
                        return;
                    }
                    List threadPoolProperties = (List) threadpools.get("executors");
                    if (threadPoolProperties.isEmpty()) {
                        return;
                    }
                    List<ThreadPoolProperties> newThreadPoolProperties = JsonUtil.objectParseList(threadPoolProperties, ArrayList.class, ThreadPoolProperties.class);

                    dynamicThreadPoolManager.refreshThreadPoolExecutor(newThreadPoolProperties);
                }
            });
        } catch (NacosException e) {
            throw new RuntimeException("nacos configuration listening exception", e);
        }
    }
}
